﻿/*
 * @Autor: PK
 * @Date: 2021-03-31 16:29:01
 * @Description: 创建Station的工厂，只需要重写 Station CreateAgency(...) 方法根据一行DataRow生成一个Station，其余逻辑已在父类实现，道路或者车站之间的互联关系请在AbstractNetwork中实现
 */

using System;
using System.Collections.Generic;
using System.Linq;
using ShkSimulation.core.factory;
using NLog;
using ShkSimulation.core.template.agency;
using ShkSimulation.core.template.model;
using ShkSimulation.carsharing.impl.elements;

namespace ShkSimulation.carsharing.impl.create {

    public class StationFactory: AgencyFactoryByCreateParam {

        public static readonly string StationId = "Id";
        public static readonly string StationName = "Name";
        public static readonly string StationVehicleCount = "VehicleCount";
        public static readonly string StationCapacity = "Capacity";
        public static readonly string StationServiceMinutes = "ServiceMinutes";
        public static readonly string StationDispatcherCount = "DispatcherCount";
        public static readonly string StationLongitude = "Longitude";
        public static readonly string StationLatitude = "Latitude";
        public static readonly string ChargeEffecience = "每小时充电量（km/h）";
        public static readonly string AvgReserveTime = "平均预约时长(M)";
        
        protected static readonly Logger logger = LogManager.GetLogger(nameof(StationFactory));
        
        public StationFactory(string resourceKey) : base(resourceKey, CreateAgency) {
        }
        
        public static Agency CreateAgency(IReadOnlyDictionary<int, Agency> createdAgencies, CreateParam createParam) {
            List<Station> createdStations = createdAgencies.Values.Cast<Station>().ToList();
            int vehicleIndex = createdStations.Sum(each => each.Vehicles.Count);
            Random random = new Random();
            Dictionary<string, object> attributes = createParam.Params;
            List<Vehicle> vehicles = new List<Vehicle>();
            string stationName = Convert.ToString(attributes[StationName]);
            int vehicleSize = Convert.ToInt32(attributes[StationVehicleCount]);
            for (int i = 0; i < vehicleSize; i++) {
                string varName = $"{stationName}的{i}号拖拉机";
                Vehicle vehicle = new Vehicle(vehicleIndex++, varName);
                vehicles.Add(vehicle);
            }
            int uniqueId = Convert.ToInt32(attributes[StationId]);
            BaseAgencyParams agencyParams = BaseAgencyParams.Create(uniqueId, 100, random.Next());
            Station station = new Station(agencyParams, vehicles);
            station.Name = stationName;
            station.QueueIndex = uniqueId;
            station.Identify = "车站";
            station.Capacity = Convert.ToDouble(attributes[StationCapacity]);
            station.ServiceMinutes = TimeSpan.FromMinutes(Convert.ToDouble(attributes[StationServiceMinutes]));
            station.Longitude = Convert.ToDouble(attributes[StationLongitude]);
            station.Latitude = Convert.ToDouble(attributes[StationLatitude]);
            int dispatcherNumber = Convert.ToInt32(attributes[StationDispatcherCount]);
            for (int i = 0; i < dispatcherNumber; i++) {
                string varName = $"{stationName}的{i}号调度员";
                Dispatcher dispatcher = new Dispatcher(varName);
                dispatcher.Identify = "调度员";
                station.Dispatchers.Enqueue(dispatcher);
            }
            List<InternalAgency> internalAgencies = new List<InternalAgency>() {
                new ChargeAgency(Convert.ToDouble(attributes[ChargeEffecience])), 
                new ReserveAgency(Convert.ToDouble(attributes[AvgReserveTime]))
            };
            station.SetInternalAgencies(internalAgencies);
            logger.Info($"创建站台 {station.Name}");
            return station;
        }


    }
}
